﻿#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<windows.h>
struct stu {
	char name[20];
	int age;
	float score;
};
int main()
{
	//打开文件，如果打开失败返回NULL
	//绝对路径
	//FILE* pf = fopen("C:\\Users\\东腾\\Desktop\\c-test.txt", "w");//"w"是写文件，文件不存在就创建新文件
	//相对路径                                                    //"r"是读文件，文件不存在就出错
	//.表示当前目录
	// ..表示上一级路径
	//FILE* pf = fopen("./../test.txt", "w");
	//FILE* pf = fopen("./data.txt", "w");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	//写文件
	//for (int i = 0; i < 26; i++) {
	//	fputc('a' + i, pf);//字符输出
	//}
	//在屏幕上输出
	///*for (int i = 0; i < 26; i++) {
	//	fputc('a' + i, stdout);
	//}*/
	//关闭文件
	//fclose(pf);
	//pf = NULL;

	//文件拷贝
	//从data.txt中读取数据写到data_copy.txt文件中
	/*FILE* pfread = fopen("./data.txt", "r");
	if (!pfread) {
		perror("fopen->data.txt");
		return 1;
	}
	FILE* pfwrite = fopen("data_copy.txt", "w");
	if (pfwrite == NULL) {
		fclose(pfread);
		pfread = NULL;
		perror("fopen->data_copy.txt");
		return 1;
	}
	}
	//文件读取结束的判定
    //判断是什么原因结束的
    if (ferror(fp))//feeor无错误出现时返回0；有错误出现时，返回一个非零值。
        puts("I/O error when reading");
	//在文件读取过程中，不能用feof函数的返回值直接用来判断文件的是否结束,feof判断是读取失败结束，还是遇到文件尾结束
    else if (feof(fp))//feof如果没有到文件尾，返回0；到达文件尾，返回一个非零值。
        puts("End of file reached successfully");*/
	//拷贝
	//文本文件读取是否结束,fgetc判断是否为EOF,fgets判断返回值是否为NULL
	//二进制文件的读取结束判断,fread判断返回值是否小于实际要读的个数
	//int ch = 0;
	//while ((ch = fgetc(pfread)) != EOF) {
	//	fputc(ch, pfwrite);//字符输出
	//}
	//fclose(pfread);
	//pfread = NULL;
	//fclose(pfwrite);
	//pfwrite = NULL;

	//FILE* pf = fopen("test.txt", "r");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	////读取
	//char arr[20] = "xxxxxxxxxxxxxxx";
	//fgets(arr, 10, pf);//9    读取n-1个,第n个位置是'\0'
	//fclose(pf);
	//pf = NULL;

	//键盘输入
	/*char arr[20] = "xxxxxxxxxxxxxxx";
	fgets(arr, 10, stdin);//字符串输入
	fputs(arr, stdout);*///字符串输出

	//写文件
	//struct stu s = { "zhangsan",20,90.5f };
	//FILE* pf = fopen("data.txt", "w");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	//fprintf(pf, "%s %s %.1f", s.name, s.age, s.score);//格式化输出
	//读文件
	//struct stu s = { 0 };
	//FILE* pf = fopen("data.txt", "r");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	//fscanf(pf, "%s %s %f", s.name, &(s.age), &(s.score));//格式化输入
	//fprintf(stdout, "%s %s %.1f", s.name, s.age, s.score);//格式化输出
	
	//struct stu s = { "zhangsan",20,90.5f };
	//FILE* pf = fopen("data.txt", "wb");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	//二进制写文件
	//fwrite(&s,sizeof(s),1,pf);

	//struct stu s = { 0 };
	//FILE* pf = fopen("data.txt", "rb");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	////二进制读文件
	//fread(&s, sizeof(s), 1, pf);//读到了返回1，没读到返回0
	//printf("%s %s %.1f", s.name, s.age, s.score);
	//fclose(pf);
	//pf = NULL;
	
     FILE* pf = fopen("data.txt", "r");
	 if (pf == NULL) {
		 perror("fopen");
		 return 1;
	 }
	 //文件指针偏移
	 int ch = fgetc(pf);
	 printf("%c\n", ch);
	 ch = fgetc(pf);
	 printf("%c\n", ch);
	 ch = fgetc(pf);
	 printf("%c\n", ch);
	 //根据文件指针的位置和偏移量来定位文件指针
	 fseek(pf, 2, SEEK_CUR);//SEEK_CUR表示文件的相对当前位置
	 //定位文件指针到f
	 //fseek(pf, 5, SEEK_SET);//SEEK_SET表示文件的相对起始位置
	 //fseek(pf, -4, SEEK_END);//SEEK_END表示文件的相对结束位置
	 ch = fgetc(pf);
	 printf("%c\n", ch);
	 int pos = ftell(pf);
	 printf("%d\n", pos);//返回文件指针相对于起始位置的偏移量
	 //rewind(pf);//让文件指针的位置回到文件的起始位置
	 fclose(pf);
	 pf = NULL;

    //文件缓冲区 - 因为有缓冲区的存在，C语言在操作文件的时候，需要刷新缓冲区或者文件操作结束时关闭文件，不然会导致数据丢失
	//FILE* pf = fopen("test.txt", "w");
	//if (pf == NULL) {
	//	perror("fopen");
	//	return 1;
	//}
	//fputs("abcdef", pf);//先将代码放在输出缓冲区
	//printf("睡眠10秒-已经写数据了，打开test.txt文件，发现文件没有内容\n");
	//Sleep(10000);
	//printf("刷新缓冲区\n");
	//fflush(pf);//刷新缓冲区时，才将输出缓冲区的数据写到文件（磁盘）
	//printf("再睡眠10秒，此时打开test.txt文件，文件有内容了\n");
	//Sleep(10000);
	//fclose(pf);//fclose在关闭文件的时候，也会刷新缓冲区
	//pf = NULL;
	return 0;
}